#include <iostream>
#include <cstdio>
#include "SDL.h"
#include "SDL_image.h"  //Support for non-BMP image files
#include <vector>
#include "gfx.h"
#include "SDL_collide.h"  //Collision detection
#include "SDL_ttf.h"      //Printing text
#define COLORKEY 255, 0, 255  //eventually, each image will be able to have its own colorkey

SDL_Surface *screen;

int output::gfxinit()
{
    if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0 ) 
    {
      fprintf(stderr, "Cannot init SDL: %s\n", SDL_GetError());
      exit(1);
    }
    atexit(SDL_Quit);
    return(0);
}

int output::setscreenmode(unsigned char depth,unsigned short screenx,unsigned short screeny)
{
    bitdepth = depth;
    width = screenx;
    height = screeny;
    screen = SDL_SetVideoMode(width, height, depth,SDL_DOUBLEBUF | SDL_SWSURFACE);
    if ( screen == NULL ) 
    {
    fprintf(stderr, "Cannot set video mode - Check Settings?: %s\n", SDL_GetError());
    exit(1);
    }
    return(0);
}

void putpixel(int x, int y, int color)
{
  unsigned int *ptr = (unsigned int*)screen->pixels;
  int lineoffset = y * (screen->pitch / 4);
  ptr[lineoffset + x] = color;
}


void output::cls() //For every y-axis line, replace every x-axis pixel with black - This seems to be a rather slow/clunky way to clear the screen
{
    int i,j;
    for(i=0;i<height;i++) 
    {
        for(j=0;j<width;j++)
        {
            putpixel(j,i,0x000000);
        }
    }
}


void output::updategfx(int px,int py)
{
	if (SDL_MUSTLOCK(screen)) 
      if (SDL_LockSurface(screen) < 0) 
        return;

//    int tick = SDL_GetTicks();
    putpixel(px,py,0xff0000);
    if (SDL_MUSTLOCK(screen)) 
      SDL_UnlockSurface(screen);

      SDL_UpdateRect(screen, 0, 0, width, height);   
}

int output::getparameter(unsigned char param)  //0=bit depth, 1=width, 2=height
{
  switch(param)
  {
    case 0:
      return bitdepth;
    case 1:
      return width;
    case 2:
      return height;
    default:
      fprintf(stderr,"Improper parameter for function getparameter - Check code.\n");
      exit(1);
  }
}

int output::pushimage(char* file)
{
    sdlimg temp;
    temp.image = IMG_Load(file);
    if (temp.image == NULL)
    {
        fprintf(stderr, "Error: '%s' could not be opened: %s\n", file, IMG_GetError());
        exit(1);
    }
    if(SDL_SetColorKey(temp.image, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(temp.image->format, COLORKEY)) == -1)  //COLORKEY Refers to the transparent color - We'll just set it through #define for now
    {
        fprintf(stderr, "Warning: colorkey will not be used, reason: %s\n", SDL_GetError());
        exit(1);
    }
    temp.position.xp = -1;
    temp.position.yp = -1;  //any negative value will be ignored by collision detection
    images.push_back(temp);  //load this image to the first available slot in the vector
    return(images.size() - 1);  //return the location of the newly pushed image in the vector
}

int output::drawimage(int imgvector, int sx, int sy, int sw, int sh, SDL_Surface *dstimg, int dx, int dy, int alpha) 
{
    if(imgvector > images.size())
        return(1);
    SDL_Surface *srcimg = images[imgvector].image;
    if ((srcimg == NULL) || (alpha == 0)) return(1); //If theres no image, or its 100% transparent.
    SDL_Rect src, dst;
    src.x = sx;  src.y = sy;  src.w = sw;  src.h = sh;
    dst.x = dx;  dst.y = dy;  dst.w = src.w;  dst.h = src.h;
    if (alpha != 255) SDL_SetAlpha(srcimg, SDL_SRCALPHA, alpha);
    SDL_BlitSurface(srcimg, &src, dstimg, &dst);
    images[imgvector].position.xp = dst.x;
    images[imgvector].position.yp = dst.y;
    return(0);
}

void output::flip()
{
    SDL_Flip(screen);
}

bool output::testcollisionsimple(unsigned short obj1, unsigned short obj2)
{
     //temporarily this will accept image references passed to it -  the obvious problem with this is that it doesn't work for multiple copies of the same image
     //down the road, this will be replaced by references to objects, when our concept of an object becomes more like a game maker object
     //Something for next revision, I guess :p
     if(obj1==obj2) return(0);  //ignore same-image requests
     sdlimg temp1,temp2;
     temp1 = images[obj1];
     temp2 = images[obj2];
     if(SDL_CollideBoundingBox(temp1.image,temp1.position.xp,temp1.position.yp,temp2.image,temp2.position.xp,temp2.position.yp)) return(1);
     return(0);
}

bool output::textinit()
{
    if(TTF_Init() == -1)
    {
         fprintf(stderr,"Cannot init SDL text output!  What is this I don't even");
         exit(1);
    }
    return(0);
}

int output::loadfont(char* font,unsigned char size)
{
    TTF_Font* temp;
    temp = TTF_OpenFont(font,size);
    if(temp == NULL)
    {
          fprintf(stderr,"Cannot load requested font!");
          exit(1);
    }
    fonts.push_back(temp);
    return(fonts.size() - 1);
}

int output::printscr(unsigned char font,char* message,unsigned char red,unsigned char green,unsigned char blue,unsigned char alpha,short x,short y)
{
     if(fonts[font] == NULL)
     {
          fprintf(stderr,"Invalid font");
          exit(1);
     }
     SDL_Color color = {red,green,blue,alpha};   
     SDL_Surface* temptext = TTF_RenderText_Blended(fonts[font], message, color); 
     if(temptext == NULL)
     {
          fprintf(stderr,"Cannot print text!  Has TTF_Init been called?");
          exit(1);
     }
     SDL_Rect src, dst;
     src.x = 0;  src.y = 0;  src.w = temptext->w;  src.h = temptext->h;
     dst.x = x;  dst.y = y;  dst.w = src.w;  dst.h = src.h;
     SDL_BlitSurface(temptext, &src, screen, &dst);
     return(0);    
}
    
    

